/*
 * Vinicius Mendes Kastrup Magalhães	-	110092513
 * Thales Teixeira Pires				-	110092474
 */

package main;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;




public class View {

	private static Controle control = new Controle();
	
	public static void main(String[] args) {
		System.out.println("Seja bem-vindo ao AFDTools!");
		System.out.println("Este programa simula algumas propriedades de um Automato Finito Deterministico.");
		System.out.println("Portanto, para comecar, entre com um AFD de acordo com as regras estabelecidas no manual.\n");
		
		menuAFD();
		
	}
	
	private static void menuAFD() {
		System.out.println("\n--------------------------Opcoes de Entrada----------------------------");
		System.out.println("1 - Ler AFD de um arquivo;");
		System.out.println("2 - Ler AFD do console;");
		System.out.println("-----------------------------------------------------------------------");
		System.out.print("Qual a opcao desejada: ");
		int opcao = readInteger();
		if (opcao == 1) lerArquivo();
		else lerConsole();
	}

	private static void menu() {
		int opcao;
		String s;
		
		System.out.println("------------------------------Opcoes---------------------------------");
		System.out.println("1 - Realizar uma Computacao;");
		System.out.println("2 - Determinar uma expressao Regular atraves do Brzozowski;");
		System.out.println("3 - Determinar uma expressao Regular atraves do Kleene;");
		System.out.println("4 - Entrar com um novo AFD;");
		System.out.println("0 - Sair do Programa.");
		System.out.println("-----------------------------------------------------------------------");
		System.out.print("Qual a opcao desejada: ");
		opcao = readInteger();
	
		while (opcao != 0) {
			switch (opcao) {
				case 1:
					System.out.println("\n-----------------------------Computacao--------------------------------");
					System.out.print("Entre com uma palavra: "); 
					s = readString();
					try {
						if (control.aceita(s)) 
							System.out.println("\n\nPalavra aceita pelo AFD!");
						else 
							System.out.println("\n\nPalavra nao aceita pelo AFD!");
					} catch (NullPointerException e) { 
						System.out.println("\n\nFalhou!"); 
					}
					System.out.println("-----------------------------------------------------------------------\n");
					break;
				case 2:
					System.out.println("\n-----------------------------Brzozowski--------------------------------");
					System.out.println("\nExpressao Regular: "+control.brzozowski()+"");
					System.out.println("-----------------------------------------------------------------------\n");
					break;
				case 3:
					System.out.println("\n-------------------------------Kleene----------------------------------");
					System.out.println("\nExpressao Regular: "+control.kleene()+"");
					System.out.println("-----------------------------------------------------------------------\n");
					break;
				case 4:
					menuAFD();
					break;
				default:
					break;	
			}
			menu();
		}
	}
	
	private static void lerArquivo() {
		System.out.print("Qual o caminho do arquivo: ");
		if (control.lerArquivo(readString())) {
			System.out.println("AFD lido com sucesso!");
			menu();
		} else {
			menuAFD();
		}
	}

	private static void lerConsole() {
		control.inicializaAutomato();
		
		int i,total;
		String s;
		StringTokenizer st;
		
		System.out.print("Digite os simbolos do alfabeto: ");
		st = new StringTokenizer(readString());
		total = st.countTokens();
		for (i=0; i<total; i++) control.addSimbolo(st.nextToken());
	
		System.out.print("Digite os estados do automato: ");
		st = new StringTokenizer(readString());
		total = st.countTokens();
		for (i=0; i<total; i++)
			control.addEstado(st.nextToken());
		
		System.out.print("Quais sao os estados finais? ");
		st = new StringTokenizer(readString());
		total = st.countTokens();
		for (i=0; i<total; i++)
			control.setEstadoFinal(st.nextToken());
		
		System.out.print("Qual o estado inicial? ");
		control.setEstadoInicial(readString());
		
		System.out.println("Para terminar, entre com cada transicao do AFD (ex: estadoA w estadoB):");
		for (i = 0; i < control.numeroTransicoes(); i++) {
			s = readString();
			st = new StringTokenizer(s);
			control.addTransicao(st.nextToken(),st.nextToken(),st.nextToken());
		}
		System.out.println("");
		menu();
	}
	
	public static int readInteger() {
		try {
			BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
			return Integer.parseInt(br.readLine());
		} catch (IOException e) {
			return 0;
		} catch (NumberFormatException e) {
			return 0;
		}
	}
	
	public static String readString() {
		try {
			BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
			return br.readLine();
		} catch (IOException e) {
			return "NULL";
		}
	}
}